#include <iostream>
using namespace std;
//使用虚拟继承的菱形继承，派生类对象的内存布局
class B{
    public:
    virtual 
        void print(){
            cout<<"B::print()"<<endl;
        }
    virtual
        void display(){
            cout<<"B::display"<<endl;
        }
    long num=0;
};
class B1:virtual public B{
public:
    void print(){
        cout<<"B1::print()"<<endl;
    }
    virtual 
        void show(){
            cout<<"B1::show()"<<endl;
        }
    long num1=10;
};
class B2:virtual public B{
public:
    virtual 
        void show(){
            cout<<"B2::show()"<<endl;
        }
    void display(){
        cout<<"B2::display()"<<endl;
    }
    long num2=20;
};
class C: public B1,public B2{
public:
    C()
    :B()
    ,B1()
    ,B2()
    {

    }
    long num3=30;
};
//B中有两个虚函数，有一个变量成员
//B1继承了B，对print()进行了覆盖同时有一个变量成员
//B2继承了B，对display()进行了覆盖，同时有一个数据成员
//C继承了B1,B2，有一个数据成员
//猜想:B1和B2的内存布局是，是先子类指向虚表的指针，然后是自己的变量成员，然后是虚基指针，然后是
//基类的变量成员，虚拟继承不继承虚表，而是一个指向基类虚表的虚基指针
void test(){
    B1 b1;
    B1* b=&b1;
    //缩小指针操控的内存，ptr是头8字节的内存
    long* ptr=(long*)b;
    //解引用得到了指向虚表的指针
    long* pl=(long*)*ptr;
    //再解引用得到了虚函数指针
    //虚表的内存布局是:虚拟继承得到了虚表，并且往虚表新加了一个元素；
    typedef void(*pFunc)(void);
    pFunc pf1=(pFunc)*pl;
    pFunc pf2=(pFunc)*(pl+1);
    pf1();
    pf2();
    //判读B1的内存布局
    cout<<sizeof(b1)<<endl;
    cout<<*(ptr)<<endl;
    cout<<*(ptr+1)<<endl;
    cout<<*(ptr+2)<<endl;
    cout<<*(ptr+3)<<endl;
}
void test2(){
    C c;
    C* pc=&c;
    long* pl=(long*)pc;
    cout<<sizeof(c)<<endl;
    cout<<*pl<<endl;
    cout<<*(pl+1)<<endl;
    cout<<*(pl+2)<<endl;
    cout<<*(pl+3)<<endl;
    cout<<*(pl+4)<<endl;
    cout<<*(pl+5)<<endl;
    cout<<*(pl+6)<<endl;
}
int main(int argc, char * argv[]){
    test();
    return 0;
}

